package com.zliblike_platform.controller;

import com.zliblike_platform.config.security.JwtTokenProvider;
import com.zliblike_platform.dto.UserLoginDTO;
import com.zliblike_platform.dto.UserRegisterDTO;
import com.zliblike_platform.entity.User;
import com.zliblike_platform.service.UserService;
import com.zliblike_platform.vo.ResponseResult;
import com.zliblike_platform.vo.UserVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Map;

/**
 * 认证控制器
 */
@Controller
public class AuthController {

    @Autowired
    private UserService userService;
    
    @Autowired
    private PasswordEncoder passwordEncoder;
    
    @Autowired
    private AuthenticationManager authenticationManager;
    
    @Autowired
    private JwtTokenProvider jwtTokenProvider;
    
    /**
     * 登录页面
     */
    @GetMapping("/login")
    public String loginPage() {
        return "login";
    }
    
    /**
     * 注册页面
     */
    @GetMapping("/register")
    public String registerPage() {
        return "register";
    }
    
    /**
     * 用户登录
     * 接口规范: /api/user/login
     * 支持两种方式：JSON请求和表单提交
     */
    @PostMapping("/api/user/login")
    public String login(
            @RequestParam(required = false) String email,
            @RequestParam(required = false) String password,
            @RequestParam(required = false, defaultValue = "false") Boolean rememberMe,
            @RequestBody(required = false) Map<String, String> loginRequest,
            HttpServletRequest request,
            HttpServletResponse response) throws IOException {
        
        // 判断请求类型：JSON或表单
        boolean isJsonRequest = request.getHeader("Content-Type") != null && 
                               request.getHeader("Content-Type").contains("application/json");
        
        // 获取登录凭据
        String loginEmail = email;
        String loginPassword = password;
        
        // 如果是JSON请求，从请求体获取参数
        if (isJsonRequest && loginRequest != null) {
            loginEmail = loginRequest.get("email");
            loginPassword = loginRequest.get("password");
            if (loginRequest.containsKey("rememberMe")) {
                rememberMe = Boolean.parseBoolean(loginRequest.get("rememberMe"));
            }
        }
        
        // 验证参数
        if (loginEmail == null || loginPassword == null) {
            if (isJsonRequest) {
                response.setContentType("application/json");
                response.getWriter().write("{\"status\":400,\"message\":\"邮箱和密码不能为空\"}");
                return null;
            } else {
                return "redirect:/login?error";
            }
        }
        
        try {
            // 使用Spring Security进行认证
            UsernamePasswordAuthenticationToken authenticationToken = 
                new UsernamePasswordAuthenticationToken(loginEmail, loginPassword);
            
            Authentication authentication = authenticationManager.authenticate(authenticationToken);
            SecurityContextHolder.getContext().setAuthentication(authentication);
            
            // 获取用户信息
            User user = userService.findByUsernameOrEmail(loginEmail);
            
            // 获取用户当日已下载次数
            Integer usedDownloads = userService.getUserDailyDownloads(user.getUserId());
            
            // 生成JWT令牌
            String jwt = jwtTokenProvider.createToken(user.getUsername(), user.getUserId());
            
            // 记录登录信息到Session (同时支持Session和JWT)
            HttpSession session = request.getSession();
            session.setAttribute("userId", user.getUserId());
            session.setAttribute("username", user.getUsername());
            session.setAttribute("email", user.getEmail());
            session.setAttribute("accountLevel", user.getAccountLevel());
            session.setAttribute("dailyDownloadLimit", user.getDailyDownloadLimit());
            session.setAttribute("remainingDownloads", user.getDailyDownloadLimit() - usedDownloads);
            
            // 处理JSON请求
            if (isJsonRequest) {
                // 构建返回数据
                Map<String, Object> data = new HashMap<>();
                data.put("userId", user.getUserId());
                data.put("email", user.getEmail());
                data.put("username", user.getUsername());
                data.put("nickname", user.getNickname());
                data.put("accountLevel", user.getAccountLevel());
                data.put("token", jwt); // 返回JWT令牌
                data.put("dailyDownloadLimit", user.getDailyDownloadLimit());
                data.put("remainingDownloads", user.getDailyDownloadLimit() - usedDownloads);
                
                response.setContentType("application/json");
                response.getWriter().write("{\"status\":200,\"message\":\"登录成功\",\"data\":" + 
                                         toJsonString(data) + "}");
                return null;
            } else {
                // 表单登录成功，重定向到首页
                return "redirect:/";
            }
        } catch (Exception e) {
            if (isJsonRequest) {
                response.setContentType("application/json");
                response.getWriter().write("{\"status\":401,\"message\":\"用户名或密码错误\"}");
                return null;
            } else {
                return "redirect:/login?error";
            }
        }
    }
    
    /**
     * 将Map转换为JSON字符串的简单实现
     */
    private String toJsonString(Map<String, Object> map) {
        StringBuilder json = new StringBuilder("{");
        boolean first = true;
        for (Map.Entry<String, Object> entry : map.entrySet()) {
            if (!first) {
                json.append(",");
            }
            first = false;
            json.append("\"").append(entry.getKey()).append("\":");
            Object value = entry.getValue();
            if (value instanceof String) {
                json.append("\"").append(value).append("\"");
            } else {
                json.append(value);
            }
        }
        json.append("}");
        return json.toString();
    }
    
    /**
     * 用户注册
     * 接口规范: /api/user/register
     * 支持两种方式：JSON请求和表单提交
     */
    @PostMapping("/api/user/register")
    public String register(
            @RequestParam(required = false) String username,
            @RequestParam(required = false) String email,
            @RequestParam(required = false) String password,
            @RequestParam(required = false) String confirmPassword,
            @RequestBody(required = false) UserRegisterDTO jsonRegisterData,
            HttpServletRequest request,
            HttpServletResponse response) throws IOException {
        
        // 判断请求类型：JSON或表单
        boolean isJsonRequest = request.getHeader("Content-Type") != null && 
                               request.getHeader("Content-Type").contains("application/json");
        
        // 创建注册数据对象
        UserRegisterDTO registerData;
        
        if (isJsonRequest && jsonRegisterData != null) {
            // 使用JSON请求体中的数据
            registerData = jsonRegisterData;
        } else {
            // 使用表单参数
            registerData = new UserRegisterDTO();
            registerData.setUsername(username);
            registerData.setEmail(email);
            registerData.setPassword(password);
            registerData.setConfirmPassword(confirmPassword);
        }
        
        // 验证数据
        if (registerData.getUsername() == null || registerData.getEmail() == null || 
            registerData.getPassword() == null) {
            if (isJsonRequest) {
                response.setContentType("application/json");
                response.getWriter().write("{\"status\":400,\"message\":\"请填写完整的注册信息\"}");
                return null;
            } else {
                return "redirect:/register?error";
            }
        }
        
        // 验证密码一致性
        if (!registerData.getPassword().equals(registerData.getConfirmPassword())) {
            if (isJsonRequest) {
                response.setContentType("application/json");
                response.getWriter().write("{\"status\":400,\"message\":\"两次密码输入不一致\"}");
                return null;
            } else {
                return "redirect:/register?error";
            }
        }
        
        // 验证用户名和邮箱是否已存在
        if (userService.isUsernameExists(registerData.getUsername())) {
            if (isJsonRequest) {
                response.setContentType("application/json");
                response.getWriter().write("{\"status\":400,\"message\":\"用户名已存在\"}");
                return null;
            } else {
                return "redirect:/register?error";
            }
        }
        
        if (userService.isEmailExists(registerData.getEmail())) {
            if (isJsonRequest) {
                response.setContentType("application/json");
                response.getWriter().write("{\"status\":400,\"message\":\"邮箱已被注册\"}");
                return null;
            } else {
                return "redirect:/register?error";
            }
        }
        
        // 注册用户
        boolean registerSuccess = userService.register(registerData);
        
        if (!registerSuccess) {
            if (isJsonRequest) {
                response.setContentType("application/json");
                response.getWriter().write("{\"status\":500,\"message\":\"注册失败，请稍后重试\"}");
                return null;
            } else {
                return "redirect:/register?error";
            }
        }
        
        // 获取新注册的用户信息
        User user = userService.findByUsernameOrEmail(registerData.getEmail());
        
        // 自动登录
        HttpSession session = request.getSession();
        session.setAttribute("userId", user.getUserId());
        session.setAttribute("username", user.getUsername());
        session.setAttribute("email", user.getEmail());
        session.setAttribute("accountLevel", user.getAccountLevel());
        session.setAttribute("dailyDownloadLimit", user.getDailyDownloadLimit());
        
        // 处理JSON请求
        if (isJsonRequest) {
            // 构建返回数据
            Map<String, Object> data = new HashMap<>();
            data.put("userId", user.getUserId());
            data.put("email", user.getEmail());
            data.put("nickname", user.getNickname());
            data.put("accountLevel", user.getAccountLevel());
            data.put("dailyDownloadLimit", user.getDailyDownloadLimit());
            data.put("remainingDownloads", user.getDailyDownloadLimit()); // 新用户未下载任何内容
            
            response.setContentType("application/json");
            response.getWriter().write("{\"status\":200,\"message\":\"注册成功\",\"data\":" + 
                                      toJsonString(data) + "}");
            return null;
        } else {
            // 表单注册成功，重定向到登录页
            return "redirect:/login?registered=true";
        }
    }
    
    /**
     * 用户登出
     */
    @GetMapping("/api/user/logout")
    @ResponseBody
    public ResponseResult<String> logout(HttpServletRequest request, HttpServletResponse response) {
        // 获取当前认证信息
        Authentication auth = SecurityContextHolder.getContext().getAuthentication();
        
        // 使用SecurityContextLogoutHandler清除认证信息
        if (auth != null) {
            new SecurityContextLogoutHandler().logout(request, response, auth);
        }
        
        // 同时清除Session
        HttpSession session = request.getSession(false);
        if (session != null) {
            session.invalidate();
        }
        
        return ResponseResult.success("退出登录成功");
    }
    
    /**
     * 检查用户名是否可用
     */
    @GetMapping("/api/user/check-username")
    @ResponseBody
    public ResponseResult<Boolean> checkUsername(@RequestParam String username) {
        boolean exists = userService.isUsernameExists(username);
        return ResponseResult.success(!exists);
    }
    
    /**
     * 检查邮箱是否可用
     */
    @GetMapping("/api/user/check-email")
    @ResponseBody
    public ResponseResult<Boolean> checkEmail(@RequestParam String email) {
        boolean exists = userService.isEmailExists(email);
        return ResponseResult.success(!exists);
    }
} 